package com.github.ompc.greys.core; import joptsimple.OptionParser; import joptsimple.OptionSet; import java.util.List; import static com.github.ompc.greys.core.util.GaStringUtils.getCauseMessage; import static java.io.File.separator; import static java.lang.System.getProperty; /** * Greys启动器 */ public class GreysLauncher { /** * greys' core jarfile */ public static final String CORE_JARFILE = getProperty("user.dir") + separator + "greys-core.jar"; /** * greys' agent jarfile */ public static final String AGENT_JARFILE = getProperty("user.dir") + separator + "greys-agent.jar"; public GreysLauncher(String[] args) throws Exception { // 解析配置文件 Configure configure = analyzeConfigure(args); // 加载agent attachAgent(configure); } /* * 解析Configure */ private Configure analyzeConfigure(String[] args) { final OptionParser parser = new OptionParser(); parser.accepts("pid").withRequiredArg().ofType(int.class).required(); parser.accepts("target").withOptionalArg().ofType(String.class); parser.accepts("multi").withOptionalArg().ofType(int.class); parser.accepts("core").withOptionalArg().ofType(String.class); parser.accepts("agent").withOptionalArg().ofType(String.class); final OptionSet os = parser.parse(args); final Configure configure = new Configure(); if (os.has("target")) { final String[] strSplit = ((String) os.valueOf("target")).split(":"); configure.setTargetIp(strSplit[0]); configure.setTargetPort(Integer.valueOf(strSplit[1])); } configure.setJavaPid((Integer) os.valueOf("pid")); configure.setGreysAgent((String) os.valueOf("agent")); configure.setGreysCore((String) os.valueOf("core")); return configure; } /* * 加载Agent */ private void attachAgent(Configure configure) throws Exception { final ClassLoader loader = Thread.currentThread().getContextClassLoader(); final Class<?> vmdClass = loader.loadClass("com.sun.tools.attach.VirtualMachineDescriptor"); final Class<?> vmClass = loader.loadClass("com.sun.tools.attach.VirtualMachine"); Object attachVmdObj = null; for (Object obj : (List<?>) vmClass.getMethod("list", (Class<?>[]) null).invoke(null, (Object[]) null)) { if ((vmdClass.getMethod("id", (Class<?>[]) null).invoke(obj, (Object[]) null)) .equals(Integer.toString(configure.getJavaPid()))) { attachVmdObj = obj; } } // if (null == attachVmdObj) { // // throw new IllegalArgumentException("pid:" + configure.getJavaPid() + " not existed."); // } Object vmObj = null; try { if (null == attachVmdObj) { // 使用 attach(String pid) 这种方式 vmObj = vmClass.getMethod("attach", String.class).invoke(null, "" + configure.getJavaPid()); } else { vmObj = vmClass.getMethod("attach", vmdClass).invoke(null, attachVmdObj); } vmClass.getMethod("loadAgent", String.class, String.class).invoke(vmObj, configure.getGreysAgent(), configure.getGreysCore() + ";" + configure.toString()); } finally { if (null != vmObj) { vmClass.getMethod("detach", (Class<?>[]) null).invoke(vmObj, (Object[]) null); } } } public static void main(String[] args) { try { new GreysLauncher(args); } catch (Throwable t) { System.err.println("start greys failed, because : " + getCauseMessage(t)); System.exit(-1); } } }